using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using FriendsNearby.Services;
using FriendsNearby.Services.Entities;
using System.Globalization;
using System.Collections.Generic;
using Facebook.Service;
using InSTEDD.Labs.Geo;
using System.IO;

namespace FriendsNearby.Fbml
{
    public partial class PeopleNearbyMap : System.Web.UI.Page
    {
        const int Relation_Me = 0;
        const int Relation_Friend = 1;
        const int Relation_Foaf = 2;

        protected void Page_Load(object sender, EventArgs e)
        {            
            FriendsNearbyFacade friendsNearbyFacade = new FriendsNearbyFacade();
            friendsNearbyFacade.FacebookSession = fbApplication.Session;

            UserInfo info = friendsNearbyFacade.LocationService.GetLocationAt(fbApplication.UserID, DateTime.Now);
            currentLatLong = info.Location;

            if (info != null && info.Location != null) {
                Map_AddMarker(info.Location, Relation_Me, "This marker represents you.", info.LastLocationUpdate);

                #region Load Map Markers of people nearby
                IEnumerable<PersonNearby> nearbyList = friendsNearbyFacade.PeopleNearbyService.GetAllPeople(fbApplication.UserID);
                foreach (PersonNearby personInfo in nearbyList)
                {
                    Map_AddPersonNearbyMarker(personInfo);
                }
                #endregion
            }
        }

        public LatLong currentLatLong;
        public string RenderCurrentLatLong
        {
            get 
            {
                // must support non-current location info to determine initial setup
                if (currentLatLong != null)
                    return string.Format(CultureInfo.InvariantCulture, "myLocation.SetLocation({0}, {1});", currentLatLong.Lat, currentLatLong.Long); 
                else
                    return string.Empty;
            }
        }

        StringBuilder mapInitialization = new StringBuilder();
        public string RenderMapInitialization
        {
            get { return "[" + mapInitialization.ToString() + "]"; }
        }

        private void Map_AddPersonNearbyMarker(PersonNearby p)
        {
            int relationKind = -1;
            switch (p.Relation)
            {
                case PersonNearbyRelation.Friend:
                    relationKind = Relation_Friend;
                    break;
                case PersonNearbyRelation.FriendOfAFriend:
                    relationKind = Relation_Foaf;
                    break;
                default:
                    throw new NotImplementedException();
            }

            #region Build InforHtml for Map's Bubble
            var infoHtmlBuffer = new StringWriter();
            var infoHtml = new HtmlTextWriter(infoHtmlBuffer );
            PersonNearbyPresentation.WriteUserNameHtml(infoHtml, p);
            infoHtml.WriteEncodedText(" at ");
            infoHtml.WriteEncodedText(PersonNearbyPresentation.GetDistanceString(p.Distance));
            infoHtml.WriteBreak();

            #endregion

            var infoHtmlEncoded = PersonNearbyPresentation.EncodeJavaScriptString(infoHtmlBuffer.GetStringBuilder().ToString());
            Map_AddMarker(p.Location, relationKind, infoHtmlEncoded, p.lastLocationUpdate);
        }

        int markerIndex = 0;
        void Map_AddMarker(LatLong location, int relationKind, string infoHtml, DateTime? lastLocationUpdate)
        {
            markerIndex++;

            if (markerIndex != 1) // if not first
                mapInitialization.Append(" , ");

            // actual marker information
            // data [{latlng,relation,messageHtml}]

            if (lastLocationUpdate.HasValue && lastLocationUpdate.Value != DateTime.MinValue)
            {
                string relativeUpdateTimeFromNowPlain = TextHelper.FormatDateTimeRelativeToNow(lastLocationUpdate.Value);
                string relativeUpdateTimeFromNowHtml = string.Format("<br/><br/>Last location update: {0}.", relativeUpdateTimeFromNowPlain);

                infoHtml += relativeUpdateTimeFromNowHtml;
            }

            mapInitialization.Append("{");
            mapInitialization.AppendFormat(CultureInfo.InvariantCulture, "latlng:new GLatLng({0},{1}),relation:{2},messageHtml:\"{3}\"", 
                location.Lat,
                location.Long,
                relationKind,
                infoHtml);
            mapInitialization.Append("}");
        }
    }
}
